<script setup lang="ts">
import { ref, defineProps, computed, onBeforeUnmount } from 'vue'
import { showToast, showDialog, Icon, Field, Button, RadioGroup, Radio } from 'vant'
import { usePPTStore } from '@/store/ppt'

const props = defineProps({
  embed: { type: Boolean, default: false }
})

const pptStore = usePPTStore()

// 生成模式：text 或 file
const generateMode = ref('text')
const textContent = ref('')
const uploadedFile = ref<any>(null)
const isUploading = ref(false)
const pollingTimer = ref<NodeJS.Timeout | null>(null)

// 计算属性从store获取数据
const isGenerating = computed(() => pptStore.isGenerating)
const currentTaskId = computed(() => pptStore.currentTaskId)
const pptData = computed(() => pptStore.currentPPTData)
const history = computed(() => pptStore.history)

// 示例文本
const examples = [
  {
    title: '数据库基础与原理',
    content: '生成一份关于数据库基础与原理的PPT，包括数据库的定义、类型（关系型、非关系型）、数据模型、数据库管理系统（DBMS）的功能等内容。'
  },
  {
    title: '数据库事务与并发控制',
    content: '生成一份关于数据库事务与并发控制的PPT，包括事务的ACID特性、并发控制机制（锁、乐观锁、悲观锁）、死锁检测与预防、事务隔离级别等内容。'
  }
]

const generatePPT = async () => {
  if (generateMode.value === 'text' && !textContent.value.trim()) {
    showToast('请输入PPT内容描述')
    return
  }
  
  if (generateMode.value === 'file' && !uploadedFile.value) {
    showToast('请上传文件')
    return
  }
  
  pptStore.setGenerating(true)
  pptStore.setCurrentTaskId('')
  pptStore.setCurrentPPTData(null)
  
  try {
    let taskId = ''
    let description = ''
    let fileName = undefined
    
    if (generateMode.value === 'text') {
      description = textContent.value
      // 文字生成PPT
      const response = await fetch(`${import.meta.env.VITE_BASE_URL}/api/ppt/text`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          text: textContent.value
        })
      })
      
      if (!response.ok) {
        throw new Error(`请求失败: ${response.status}`)
      }
      
      const result = await response.json()
      if (result.code !== 200) {
        throw new Error(result.msg || '生成失败')
      }
      
      taskId = result.data.id
    } else {
      description = `基于文件"${uploadedFile.value.name}"生成PPT`
      fileName = uploadedFile.value.name
      // 文件生成PPT
      if (!uploadedFile.value.fileUrl) {
        throw new Error('文件上传失败，请重试')
      }
      
      const response = await fetch(`${import.meta.env.VITE_BASE_URL}/api/ppt/file`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: `file_url=${encodeURIComponent(uploadedFile.value.fileUrl)}`
      })
      
      if (!response.ok) {
        throw new Error(`请求失败: ${response.status}`)
      }
      
      const result = await response.json()
      if (result.code !== 200) {
        throw new Error(result.msg || '生成失败')
      }
      
      taskId = result.data.id
    }
    
    pptStore.setCurrentTaskId(taskId)
    
    // 添加到历史记录（初始状态）
    pptStore.addToHistory({
      taskId,
      title: '正在生成中...',
      description,
      mode: generateMode.value as 'text' | 'file',
      fileName,
      previewUrl: '',
      status: 1
    })
    
    showToast('PPT生成任务已提交，正在生成中...')
    
    // 开始轮询检查生成状态
    startPolling()
    
  } catch (error) {
    console.error('生成PPT失败:', error)
    showToast(error instanceof Error ? error.message : '生成PPT失败，请重试')
    pptStore.setGenerating(false)
  }
}

const startPolling = () => {
  checkPPTStatus()
}

const stopPolling = () => {
  if (pollingTimer.value) {
    clearTimeout(pollingTimer.value)
    pollingTimer.value = null
  }
}

const checkPPTStatus = async () => {
  if (!currentTaskId.value) return
  
  try {
    const response = await fetch(`${import.meta.env.VITE_BASE_URL}/api/ppt/get/id?id=${currentTaskId.value}`)
    
    if (!response.ok) {
      throw new Error(`查询失败: ${response.status}`)
    }
    
    const result = await response.json()
    if (result.code !== 200) {
      throw new Error(result.msg || '查询失败')
    }
    
    const data = result.data
    pptStore.setCurrentPPTData(data)
    
    // 更新历史记录
    pptStore.updateHistoryItem(currentTaskId.value, {
      title: data.ppt_title || '正在生成中...',
      pageCount: data.page_count,
      previewUrl: data.preview_url || '',
      status: data.status
    })
    
    if (data.status === 2) {
      // 生成完成
      pptStore.setGenerating(false)
      stopPolling()
      showToast('PPT生成完成！')
      
      // 获取下载链接
      try {
        const downloadResponse = await fetch(`${import.meta.env.VITE_BASE_URL}/api/ppt/download/${currentTaskId.value}`, {
          method: 'POST'
        })
        if (downloadResponse.ok) {
          const downloadResult = await downloadResponse.json()
          if (downloadResult.code === 200) {
            pptStore.updateHistoryItem(currentTaskId.value, {
              downloadUrl: downloadResult.data.download_url
            })
          }
        }
      } catch (error) {
        console.error('获取下载链接失败:', error)
      }
    } else if (data.status === 3) {
      // 生成失败
      pptStore.setGenerating(false)
      stopPolling()
      showToast('PPT生成失败，请重试')
    } else {
      // 继续轮询
      pollingTimer.value = setTimeout(checkPPTStatus, 3000)
    }
  } catch (error) {
    console.error('查询PPT状态失败:', error)
    // 继续轮询，避免因网络问题中断
    pollingTimer.value = setTimeout(checkPPTStatus, 5000)
  }
}

const downloadPPT = async () => {
  if (!currentTaskId.value) {
    showToast('没有可下载的PPT')
    return
  }
  
  // 先从历史记录中查找下载链接
  const historyItem = history.value.find(item => item.taskId === currentTaskId.value)
  if (historyItem?.downloadUrl) {
    window.open(historyItem.downloadUrl, '_blank')
    showToast('PPT下载已开始')
    return
  }
  
  try {
    const response = await fetch(`${import.meta.env.VITE_BASE_URL}/api/ppt/download/${currentTaskId.value}`, {
      method: 'POST'
    })
    
    if (!response.ok) {
      throw new Error(`下载失败: ${response.status}`)
    }
    
    const result = await response.json()
    if (result.code !== 200) {
      throw new Error(result.msg || '下载失败')
    }
    
    // 在新窗口打开下载链接
    window.open(result.data.download_url, '_blank')
    showToast('PPT下载已开始')
    
    // 更新历史记录中的下载链接
    pptStore.updateHistoryItem(currentTaskId.value, {
      downloadUrl: result.data.download_url
    })
  } catch (error) {
    console.error('下载PPT失败:', error)
    showToast('下载失败，请重试')
  }
}

// 自定义文件上传处理
const handleFileSelect = async (event: Event) => {
  const target = event.target as HTMLInputElement
  const file = target.files?.[0]
  
  if (!file) return
  
  // 检查文件类型
  const allowedTypes = ['.pdf', '.doc', '.docx', '.txt', '.ppt', '.pptx']
  const fileExtension = '.' + file.name.split('.').pop()?.toLowerCase()
  
  if (!allowedTypes.includes(fileExtension)) {
    showToast('不支持的文件格式')
    target.value = ''
    return
  }
  
  // 检查文件大小（50MB限制）
  if (file.size > 50 * 1024 * 1024) {
    showToast('文件大小不能超过50MB')
    target.value = ''
    return
  }
  
  isUploading.value = true
  showToast('正在上传文件...')
  
  try {
    const formData = new FormData()
    formData.append('file', file)
    
    const response = await fetch(`${import.meta.env.VITE_BASE_URL}/api/minio/upload`, {
      method: 'POST',
      body: formData
    })
    
    if (!response.ok) {
      throw new Error(`上传失败: ${response.status}`)
    }
    
    const fileUrl = await response.text()
    uploadedFile.value = {
      name: file.name,
      size: file.size,
      fileUrl: fileUrl
    }
    
    showToast('文件上传成功')
  } catch (error) {
    console.error('文件上传失败:', error)
    showToast('文件上传失败，请重试')
  } finally {
    isUploading.value = false
    target.value = ''
  }
}

const triggerFileInput = () => {
  const fileInput = document.getElementById('file-input') as HTMLInputElement
  fileInput?.click()
}

const removeUploadedFile = () => {
  uploadedFile.value = null
}

const clearAll = () => {
  showDialog({
    title: '清空确认',
    message: '确定要清空所有内容和历史记录吗？',
    showCancelButton: true,
    cancelButtonText: '取消',
    confirmButtonText: '确定',
    confirmButtonColor: '#4080ff',
  }).then(() => {
    textContent.value = ''
    uploadedFile.value = null
    pptStore.setCurrentTaskId('')
    pptStore.setCurrentPPTData(null)
    pptStore.clearHistory()
    stopPolling()
    pptStore.setGenerating(false)
    showToast('已清空')
  }).catch(() => {})
}

const clearHistory = () => {
  showDialog({
    title: '清空历史记录',
    message: '确定要清空所有历史记录吗？',
    showCancelButton: true,
    cancelButtonText: '取消',
    confirmButtonText: '确定',
    confirmButtonColor: '#4080ff',
  }).then(() => {
    pptStore.clearHistory()
    showToast('历史记录已清空')
  }).catch(() => {})
}

const loadExample = (example: any) => {
  generateMode.value = 'text'
  textContent.value = example.content
}

const loadFromHistory = (item: any) => {
  if (item.mode === 'text') {
    generateMode.value = 'text'
    textContent.value = item.description
  } else {
    generateMode.value = 'file'
    // 文件模式下只能重新上传
    showToast('请重新上传文件')
  }
  
  // 如果是已完成的PPT，直接加载预览
  if (item.status === 2) {
    pptStore.setCurrentTaskId(item.taskId)
    pptStore.setCurrentPPTData({
      ppt_title: item.title,
      page_count: item.pageCount,
      preview_url: item.previewUrl,
      status: item.status,
      created_at: new Date(item.timestamp).toISOString()
    })
  }
}

const removeHistoryItem = (item: any, event: Event) => {
  event.stopPropagation()
  showDialog({
    title: '删除确认',
    message: '确定要删除这条历史记录吗？',
    showCancelButton: true,
    cancelButtonText: '取消',
    confirmButtonText: '删除',
    confirmButtonColor: '#ee0a24',
  }).then(() => {
    pptStore.removeHistoryItem(item.id)
    showToast('已删除')
  }).catch(() => {})
}

const formatTimestamp = (timestamp: number) => {
  const date = new Date(timestamp)
  return date.toLocaleString('zh-CN')
}

const formatFileSize = (size: number) => {
  if (size < 1024) return size + ' B'
  if (size < 1024 * 1024) return (size / 1024).toFixed(1) + ' KB'
  return (size / (1024 * 1024)).toFixed(1) + ' MB'
}

onBeforeUnmount(() => {
  stopPolling()
})
</script>

<template>
  <div class="ppt-container" :class="{ embed: props.embed }">
    <div class="web-header">
      <div class="title">一键做PPT</div>
      <div class="actions">
        <div class="clear-button" @click="clearAll">
          <Icon name="delete-o" size="16" />
          <span>清空</span>
        </div>
      </div>
    </div>
    
    <div class="ppt-content">
      <!-- 左侧：输入区域 -->
      <div class="input-section">
        <div class="section-header">
          <h3>PPT生成方式</h3>
        </div>
        
        <!-- 生成模式选择 -->
        <div class="mode-selector">
          <RadioGroup v-model="generateMode" direction="horizontal">
            <Radio name="text" icon-size="16px">文字描述</Radio>
            <Radio name="file" icon-size="16px">文件上传</Radio>
          </RadioGroup>
        </div>
        
        <!-- 文字模式 -->
        <div v-if="generateMode === 'text'" class="text-mode">
          <div class="examples-section">
            <span class="example-label">示例：</span>
            <div class="examples-list">
              <button 
                v-for="example in examples" 
                :key="example.title"
                class="example-btn"
                @click="loadExample(example)"
              >
                {{ example.title }}
              </button>
            </div>
          </div>
          
          <Field
            v-model="textContent"
            type="textarea"
            rows="5"
            class="text-textarea"
            placeholder="请描述您想要生成的PPT内容，例如：生成一份关于人工智能发展历程的PPT，包含发展背景、技术突破、应用领域、未来趋势等内容..."
            autosize
          />
          
          <div class="tips">
            <Icon name="info-o" size="14" color="#1989fa" />
            <span>提示：描述越详细，生成的PPT内容越丰富。建议包含主题、目标受众、主要章节等信息。</span>
          </div>
        </div>
        
        <!-- 文件模式 -->
        <div v-else class="file-mode">
          <div class="upload-section">
            <!-- 自定义文件上传组件 -->
            <div v-if="!uploadedFile" class="custom-upload">
              <div class="upload-area" @click="triggerFileInput">
                <Icon name="plus" size="40" color="#1989fa" />
                <p>点击上传文件</p>
                <span>支持 PDF、Word、PPT、TXT 等格式</span>
                <span class="size-limit">文件大小限制：50MB</span>
              </div>
              <input 
                id="file-input"
                type="file" 
                accept=".pdf,.doc,.docx,.txt,.ppt,.pptx"
                style="display: none"
                @change="handleFileSelect"
              />
            </div>
            
            <div v-else class="uploaded-file">
              <div class="file-info">
                <Icon name="description" size="32" color="#1989fa" />
                <div class="file-details">
                  <div class="file-name">{{ uploadedFile.name }}</div>
                  <div class="file-meta">
                    <span class="file-size">{{ formatFileSize(uploadedFile.size) }}</span>
                    <span class="file-status">上传成功</span>
                  </div>
                </div>
              </div>
              <Icon 
                name="cross" 
                size="16" 
                color="#999"
                class="remove-icon"
                @click="removeUploadedFile"
              />
            </div>
            
            <!-- 上传进度 -->
            <div v-if="isUploading" class="upload-progress">
              <Icon name="loading" size="16" class="loading-icon" />
              <span>正在上传文件...</span>
            </div>
          </div>
          
          <div class="tips">
            <Icon name="info-o" size="14" color="#1989fa" />
            <span>系统将基于您上传的文件内容自动生成PPT演示文稿。</span>
          </div>
        </div>
        
        <!-- 生成按钮 -->
        <div class="action-buttons">
          <Button 
            type="primary" 
            :loading="isGenerating"
            :disabled="(generateMode === 'text' && !textContent.trim()) || (generateMode === 'file' && !uploadedFile)"
            @click="generatePPT"
            class="generate-btn"
          >
            <Icon name="play-circle-o" size="16" />
            {{ isGenerating ? '生成中...' : '生成PPT' }}
          </Button>
        </div>
      </div>
      
      <!-- 右侧：预览区域 -->
      <div class="preview-section">
        <div class="section-header">
          <h3>PPT预览</h3>
          <Button 
            v-if="pptData && pptData.status === 2"
            type="success"
            size="small"
            @click="downloadPPT"
            class="download-btn"
          >
            <Icon name="down" size="14" />
            下载PPT
          </Button>
        </div>
        
        <div class="preview-container">
          <!-- 空状态 -->
          <div v-if="!isGenerating && !pptData" class="preview-placeholder">
            <Icon name="play-circle-o" size="64" color="#c8c9cc" />
            <p>请输入内容或上传文件并点击生成PPT</p>
            <div class="placeholder-features">
              <p>支持功能：</p>
              <ul>
                <li>• 智能内容分析生成</li>
                <li>• 自动排版和美化</li>
                <li>• 多种主题模板</li>
                <li>• 一键下载PPTX文件</li>
              </ul>
            </div>
          </div>
          
          <!-- 生成中状态 -->
          <div v-else-if="(isGenerating || isUploading) && (!pptData || !pptData.state_description || !pptData.state_description.includes('正在输出文件'))" class="generating-state">
            <Icon name="loading" size="48" color="#1989fa" class="loading-icon" />
            <h4>正在生成PPT中...</h4>
            <p v-if="pptData">{{ pptData.state_description || '正在处理您的内容' }}</p>
            <p v-else>正在分析内容并生成演示文稿</p>
            <div v-if="pptData && pptData.progress" class="progress-info">
              <span>生成进度：{{ pptData.progress }}%</span>
            </div>
          </div>
          
          <!-- PPT预览 -->
          <div v-else-if="pptData && (pptData.status === 2 || (pptData.state_description && pptData.state_description.includes('正在输出文件')))" class="ppt-preview">
            <!-- PPT基本信息 -->
            <div class="ppt-info">
              <h4>{{ pptData.ppt_title || '正在生成PPT...' }}</h4>
              <div class="ppt-meta">
                <span v-if="pptData.page_count">共 {{ pptData.page_count }} 页</span>
                <span v-if="pptData.created_at">{{ formatTimestamp(new Date(pptData.created_at).getTime()) }}</span>
                <span v-if="pptData.state_description && pptData.status !== 2">{{ pptData.state_description }}</span>
              </div>
            </div>
            
            <!-- PPT预览iframe -->
            <div class="ppt-iframe-container">
              <iframe 
                :src="pptData.preview_url" 
                class="ppt-iframe"
                frameborder="0"
                allowfullscreen
              ></iframe>
            </div>
          </div>
          
          <!-- 生成失败状态 -->
          <div v-else-if="pptData && pptData.status === 3" class="error-state">
            <Icon name="warning-o" size="48" color="#ee0a24" />
            <h4>PPT生成失败</h4>
            <p>{{ pptData.state_description || '生成过程中出现错误，请重试' }}</p>
            <Button type="primary" @click="generatePPT">重新生成</Button>
          </div>
        </div>
      </div>
      
      <!-- 历史记录 -->
      <div v-if="history.length > 0" class="history-section">
        <div class="section-header">
          <h3>历史记录</h3>
          <span class="history-count">{{ history.length }} 条记录</span>
        </div>
        
        <div class="history-list">
          <div 
            v-for="item in history" 
            :key="item.id"
            class="history-item"
            :class="{ 'generating': item.status === 1, 'completed': item.status === 2, 'failed': item.status === 3 }"
            @click="loadFromHistory(item)"
          >
            <div class="history-preview">
              <div v-if="item.status === 1" class="preview-loading">
                <Icon name="loading" size="24" class="loading-icon" />
              </div>
              <div v-else-if="item.status === 3" class="preview-error">
                <Icon name="warning-o" size="24" color="#ee0a24" />
              </div>
              <iframe 
                v-else-if="item.previewUrl" 
                :src="item.previewUrl" 
                class="preview-iframe"
                frameborder="0"
              ></iframe>
              <div v-else class="preview-placeholder">
                <Icon name="play-circle-o" size="24" color="#c8c9cc" />
              </div>
            </div>
            
            <div class="history-info">
              <div class="history-title">{{ item.title }}</div>
              <div class="history-description">{{ item.description.substring(0, 80) }}{{ item.description.length > 80 ? '...' : '' }}</div>
              <div class="history-meta">
                <span class="history-mode">{{ item.mode === 'text' ? '文字生成' : '文件生成' }}</span>
                <span v-if="item.fileName" class="history-file">{{ item.fileName }}</span>
                <span v-if="item.pageCount" class="history-pages">{{ item.pageCount }}页</span>
                <span class="history-time">{{ formatTimestamp(item.timestamp) }}</span>
              </div>
            </div>
            
            <div class="history-actions">
              <Icon 
                name="delete-o" 
                size="16" 
                color="#ee0a24"
                class="delete-icon"
                @click="removeHistoryItem(item, $event)"
              />
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.ppt-container {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 600px;
  background-color: #fff;
  
  .web-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 24px;
    border-bottom: 1px solid #ebeef5;
    background-color: #fff;
    position: sticky;
    top: 0;
    z-index: 100;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
    
    .title {
      font-size: 18px;
      font-weight: 500;
      color: #333;
    }
    
    .actions {
      .clear-button {
        display: flex;
        align-items: center;
        gap: 6px;
        padding: 8px 16px;
        background-color: #f5f5f5;
        border-radius: 4px;
        color: #606266;
        font-size: 14px;
        cursor: pointer;
        transition: all 0.2s;
        
        &:hover {
          background-color: #e8e8e8;
        }
      }
    }
  }
  
  .ppt-content {
    flex: 1;
    padding: 24px;
    overflow-y: auto;
    display: grid;
    grid-template-columns: 1fr 2fr;
    gap: 24px;
    
    .section-header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-bottom: 16px;
      
      h3 {
        margin: 0;
        font-size: 16px;
        font-weight: 600;
        color: #333;
      }
    }
    
    .input-section {
      .mode-selector {
        margin-bottom: 20px;
        
        :deep(.van-radio-group) {
          display: flex;
          gap: 16px;
        }
        
        :deep(.van-radio) {
          flex: 1;
          padding: 12px 16px;
          border: 1px solid #e1e5e9;
          border-radius: 8px;
          background: #fafbfc;
          transition: all 0.2s;
          
          &:hover {
            border-color: #1989fa;
            background: #f0f9ff;
          }
          
          &.van-radio--checked {
            border-color: #1989fa;
            background: #e6f7ff;
            color: #1989fa;
          }
        }
      }
      
      .text-mode {
        .examples-section {
          margin-bottom: 16px;
          
          .example-label {
            font-size: 12px;
            color: #666;
            margin-bottom: 8px;
            display: block;
          }
          
          .examples-list {
            display: flex;
            gap: 8px;
            flex-wrap: wrap;
            
            .example-btn {
              padding: 6px 12px;
              background: #f0f9ff;
              color: #1989fa;
              border: 1px solid #b3d8ff;
              border-radius: 16px;
              font-size: 12px;
              cursor: pointer;
              transition: all 0.2s;
              
              &:hover {
                background: #e6f7ff;
                border-color: #91d5ff;
              }
            }
          }
        }
        
        .text-textarea {
          margin-bottom: 12px;
          
          :deep(.van-field__control) {
            font-size: 14px;
            line-height: 1.6;
            background: #f8f9fa;
            border-radius: 8px;
            padding: 16px;
            border: 1px solid #e1e5e9;
            
            &:focus {
              border-color: #1989fa;
              box-shadow: 0 0 0 2px rgba(25, 137, 250, 0.1);
            }
          }
        }
      }
      
      .file-mode {
        .upload-section {
          margin-bottom: 12px;
          
          .custom-upload {
            .upload-area {
              border: 2px dashed #e1e5e9;
              border-radius: 12px;
              padding: 40px 20px;
              text-align: center;
              background: #fafbfc;
              transition: all 0.3s;
              cursor: pointer;
              
              &:hover {
                border-color: #1989fa;
                background: #f0f9ff;
              }
              
              p {
                margin: 12px 0 8px 0;
                font-size: 16px;
                color: #333;
                font-weight: 500;
              }
              
              span {
                display: block;
                font-size: 12px;
                color: #999;
                margin-bottom: 4px;
              }
              
              .size-limit {
                font-size: 12px;
                color: #999;
              }
            }
          }
          
          .uploaded-file {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 16px;
            background: #f0f9ff;
            border: 1px solid #b3d8ff;
            border-radius: 8px;
            
            .file-info {
              display: flex;
              align-items: center;
              gap: 12px;
              flex: 1;
              
              .file-details {
                .file-name {
                  font-size: 14px;
                  color: #333;
                  font-weight: 500;
                  margin-bottom: 2px;
                }
                
                .file-meta {
                  .file-size {
                    font-size: 12px;
                    color: #666;
                  }
                  
                  .file-status {
                    font-size: 12px;
                    color: #52c41a;
                  }
                }
              }
            }
            
            .remove-icon {
              cursor: pointer;
              transition: color 0.2s;
              padding: 4px;
              border-radius: 4px;
              
              &:hover {
                color: #ee0a24;
                background: rgba(238, 10, 36, 0.1);
              }
            }
          }
          
          .upload-progress {
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 16px;
            background: #f0f9ff;
            border-radius: 8px;
            margin-top: 12px;
            
            .loading-icon {
              animation: rotate 1s linear infinite;
              margin-right: 8px;
            }
            
            span {
              font-size: 14px;
              color: #666;
            }
          }
        }
      }
      
      .tips {
        display: flex;
        align-items: flex-start;
        gap: 8px;
        padding: 12px;
        background: #f0f9ff;
        border-radius: 8px;
        margin-bottom: 16px;
        font-size: 13px;
        color: #666;
        line-height: 1.5;
      }
      
      .action-buttons {
        .generate-btn {
          display: flex;
          align-items: center;
          gap: 8px;
          padding: 12px 24px;
          background: linear-gradient(135deg, #1989fa, #40a9ff);
          border: none;
          border-radius: 8px;
          font-weight: 500;
          font-size: 15px;
          width: 100%;
          justify-content: center;
          
          &:hover:not(:disabled) {
            background: linear-gradient(135deg, #1670cc, #369eea);
            transform: translateY(-1px);
            box-shadow: 0 4px 12px rgba(25, 137, 250, 0.3);
          }
          
          &:disabled {
            opacity: 0.6;
          }
        }
      }
    }
    
    .preview-section {
      .section-header {
        flex-direction: row !important;
        align-items: center;
      }
      
      .preview-container {
        border: 2px solid #e1e5e9;
        border-radius: 12px;
        min-height: 400px;
        background: #fafbfc;
        
        .preview-placeholder {
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;
          height: 400px;
          text-align: center;
          color: #666;
          padding: 20px;
          
          p {
            margin: 16px 0;
            font-size: 14px;
          }
          
          .placeholder-features {
            margin-top: 20px;
            
            p {
              font-size: 13px;
              color: #888;
              margin-bottom: 8px;
            }
            
            ul {
              text-align: left;
              display: inline-block;
              font-size: 12px;
              color: #999;
              line-height: 1.8;
              
              li {
                margin-bottom: 4px;
              }
            }
          }
        }
        
        .generating-state {
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;
          height: 400px;
          text-align: center;
          padding: 20px;
          
          .loading-icon {
            animation: rotate 1s linear infinite;
            margin-bottom: 16px;
          }
          
          h4 {
            margin: 0 0 8px 0;
            color: #1989fa;
            font-size: 16px;
          }
          
          p {
            margin: 8px 0;
            color: #666;
            font-size: 14px;
          }
          
          .progress-info {
            margin-top: 16px;
            padding: 8px 16px;
            background: #e6f7ff;
            border-radius: 16px;
            color: #1989fa;
            font-size: 12px;
          }
        }
        
        .ppt-preview {
          padding: 20px;
          height: 100%;
          display: flex;
          flex-direction: column;
          
          .ppt-info {
            margin-bottom: 16px;
            
            h4 {
              margin: 0 0 8px 0;
              color: #333;
              font-size: 16px;
              font-weight: 600;
            }
            
            .ppt-meta {
              display: flex;
              gap: 16px;
              font-size: 12px;
              color: #666;
            }
          }
          
          .ppt-iframe-container {
            flex: 1;
            min-height: 300px;
            border-radius: 8px;
            overflow: hidden;
            border: 1px solid #e1e5e9;
            margin-bottom: 16px;
            
            .ppt-iframe {
              width: 100%;
              height: 100%;
              min-height: 300px;
            }
          }
        }
        
        .error-state {
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;
          height: 400px;
          text-align: center;
          padding: 20px;
          
          h4 {
            margin: 16px 0 8px 0;
            color: #ee0a24;
            font-size: 16px;
          }
          
          p {
            margin: 8px 0 20px 0;
            color: #666;
            font-size: 14px;
          }
        }
      }
      
      .download-btn {
        display: flex;
        align-items: center;
        gap: 6px;
        background: #52c41a;
        border: none;
        
        &:hover {
          background: #389e0d;
          transform: translateY(-1px);
          box-shadow: 0 2px 8px rgba(82, 196, 26, 0.3);
        }
      }
    }
  }
  
  &.embed {
    .web-header {
      position: static !important;
      box-shadow: none;
    }
  }
  
  .history-section {
    grid-column: 1 / -1;
    margin-top: 24px;
    
    .section-header {
      .history-count {
        font-size: 12px;
        color: #666;
        background: #f5f5f5;
        padding: 2px 8px;
        border-radius: 12px;
      }
    }
    
    .history-list {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
      gap: 16px;
      
      .history-item {
        border: 1px solid #e1e5e9;
        border-radius: 12px;
        padding: 16px;
        cursor: pointer;
        transition: all 0.2s;
        background: #fff;
        position: relative;
        
        &:hover {
          border-color: #1989fa;
          box-shadow: 0 2px 8px rgba(25, 137, 250, 0.15);
          transform: translateY(-2px);
        }
        
        &.generating {
          border-color: #1989fa;
          background: #f0f9ff;
        }
        
        &.failed {
          border-color: #ee0a24;
          background: #fff1f0;
        }
        
        &.completed {
          border-color: #52c41a;
          
          &:hover {
            border-color: #389e0d;
          }
        }
        
        .history-preview {
          width: 100%;
          height: 120px;
          overflow: hidden;
          border-radius: 8px;
          background: #f8f9fa;
          display: flex;
          align-items: center;
          justify-content: center;
          margin-bottom: 12px;
          
          .preview-loading {
            .loading-icon {
              animation: rotate 1s linear infinite;
              color: #1989fa;
            }
          }
          
          .preview-iframe {
            width: 100%;
            height: 100%;
            border: none;
            pointer-events: none;
          }
          
          .preview-placeholder, .preview-error {
            display: flex;
            align-items: center;
            justify-content: center;
            width: 100%;
            height: 100%;
          }
        }
        
        .history-info {
          .history-title {
            font-size: 14px;
            font-weight: 600;
            color: #333;
            margin-bottom: 4px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
          }
          
          .history-description {
            font-size: 12px;
            color: #666;
            line-height: 1.4;
            margin-bottom: 8px;
            display: -webkit-box;
            -webkit-line-clamp: 2;
            -webkit-box-orient: vertical;
            overflow: hidden;
          }
          
          .history-meta {
            display: flex;
            flex-wrap: wrap;
            gap: 8px;
            font-size: 11px;
            
            span {
              padding: 2px 6px;
              border-radius: 4px;
              background: #f5f5f5;
              color: #666;
              
              &.history-mode {
                background: #e6f7ff;
                color: #1989fa;
              }
              
              &.history-file {
                background: #fff7e6;
                color: #fa8c16;
              }
              
              &.history-pages {
                background: #f6ffed;
                color: #52c41a;
              }
              
              &.history-time {
                background: #f5f5f5;
                color: #999;
              }
            }
          }
        }
        
        .history-actions {
          position: absolute;
          top: 12px;
          right: 12px;
          
          .delete-icon {
            padding: 4px;
            cursor: pointer;
            border-radius: 4px;
            transition: all 0.2s;
            
            &:hover {
              background: rgba(238, 10, 36, 0.1);
            }
          }
        }
      }
    }
  }
  
  @media (max-width: 1200px) {
    .ppt-content {
      grid-template-columns: 1fr;
      gap: 16px;
    }
    
    .history-section .history-list {
      grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    }
  }
}

@keyframes rotate {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}
</style> 